package tc.de.krawallmann.gravoblocks.game;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.state.transition.FadeInTransition;
import org.newdawn.slick.state.transition.FadeOutTransition;

import tc.de.krawallmann.extension.HighscoresExtension;
import tc.de.krawallmann.extension.SettingsExtension;
import tc.de.krawallmann.gravoblocks.resource.Language;
import tc.de.krawallmann.gravoblocks.score.Score;
import tc.de.krawallmann.slick.game.AbstractExtendableGame;
import tc.de.krawallmann.slick.game.AbstractMMenuState;
import tc.de.krawallmann.twl.RootPane;
import tc.de.krawallmann.twl.widgets.MulticolorLabel;
import de.matthiasmann.twl.Button;
import de.matthiasmann.twl.EditField;
import de.matthiasmann.twl.Label;

/**
 * The Class ScoresState enablkes the user to enter his name after scoring
 * 
 * @author KrawallMann
 * @version 1.0
 */
public class EnterScoreState extends AbstractMMenuState {
	/** The backButton button. */
	private transient Button backButton;

	/** The click. */
	private transient Sound click;

	private String gamemode;

	private transient String lastEnteredName = Language.getString("EnterScoreState.1");//$NON-NLS-1$

	/** The level. */
	private int level;

	/** The level label. */
	private transient Label levelLabel;

	/** The level text label. */
	private transient MulticolorLabel levelTextLabel;

	/** The lines. */
	private int lines;

	/** The name field. */
	private transient EditField nameField;

	/** The name text label. */
	private transient MulticolorLabel nameTextLabel;

	/** The ok button. */
	private transient Button okButton;

	/** The rows label. */
	private transient Label rowsLabel;

	/** The rows text label. */
	private transient MulticolorLabel rowsTextLabel;

	/** The score. */
	private int score;

	/** The score label. */
	private transient Label scoreLabel;

	/** The "scores" label. */
	private transient Label scoresLabel;

	/** The score text label. */
	private transient MulticolorLabel scoreTextLabel;

	/**
	 * Instantiates a new EnterScoreState.
	 * 
	 * @param menuID
	 *            the menu's id
	 * @param game
	 *            the game
	 */
	public EnterScoreState(final int menuID, final AbstractExtendableGame game) {
		super(menuID, game);
	}

	public String getGamemode() {
		return gamemode;
	}

	/**
	 * Gets the level.
	 * 
	 * @return the level
	 */
	public int getLevel() {
		return level;
	}

	/**
	 * Gets the lines.
	 * 
	 * @return the lines
	 */
	public int getLines() {
		return lines;
	}

	/**
	 * Gets the score.
	 * 
	 * @return the score
	 */
	public int getScore() {
		return score;
	}

	/*
	 * (non-Javadoc)
	 * @see tc.de.krawallmann.slick.game.AbstractMMenuState#init(org.newdawn.
	 * slick.GameContainer, org.newdawn.slick.state.StateBasedGame)
	 */
	@Override
	public void init(final GameContainer container, final StateBasedGame game)
			throws SlickException {
		super.init(container, game);
		click = new Sound("tc/de/krawallmann/gravoblocks/resource/click.wav"); //$NON-NLS-1$
		setBackground(new Image("tc/de/krawallmann/gravoblocks/resource/mainmenu.jpg")); //$NON-NLS-1$
	}

	/*
	 * (non-Javadoc)
	 * @see tc.de.krawallmann.twlslick.BasicTWLGameState#layoutRootPane()
	 */
	@Override
	public void layoutRootPane() {
		super.layoutRootPane();

		// Adjust the sizes
		backButton.adjustSize();
		okButton.adjustSize();
		scoreLabel.adjustSize();
		rowsLabel.adjustSize();
		levelLabel.adjustSize();
		levelTextLabel.adjustSize();
		scoreTextLabel.adjustSize();
		rowsTextLabel.adjustSize();
		nameTextLabel.adjustSize();
		nameField.setSize(310, scoreLabel.getHeight());

		// Set the positions
		backButton.setPosition(750 - backButton.getWidth(), 500);
		okButton.setPosition(backButton.getX() - okButton.getWidth() - 20, 500);
		scoresLabel.adjustSize();
		scoresLabel.setPosition((getContainer().getWidth() - scoresLabel.getWidth()) / 2, 20);
		scoreLabel.setPosition(50, 150);
		rowsLabel.setPosition(316, 150);
		levelLabel.setPosition(582, 150);
		levelTextLabel.setPosition(582 + (168 - levelTextLabel.getWidth()) / 2, 205);
		scoreTextLabel.setPosition(50 + (168 - scoreTextLabel.getWidth()) / 2, 205);
		rowsTextLabel.setPosition(316 + (168 - rowsTextLabel.getWidth()) / 2, 205);
		nameField.setPosition(50, 320);
		nameTextLabel.setPosition(scoreTextLabel.getX(), 390);
	}

	/*
	 * (non-Javadoc)
	 * @see tc.de.krawallmann.slick.game.AbstractMMenuState#leave(org.newdawn
	 * .slick.GameContainer, org.newdawn.slick.state.StateBasedGame)
	 */
	@Override
	public void leave(final GameContainer container, final StateBasedGame game)
			throws SlickException {
		score = 0;
		level = 0;
		lines = 0;
		gamemode = Score.NORMAL;
		((ScoresState) game.getState(GravoBlocksGame.VIEWSCORESSTATE)).reload();
		super.leave(container, game);
	}

	public void setGamemode(final String gamemode) {
		this.gamemode = gamemode;
	}

	/**
	 * Sets the level.
	 * 
	 * @param level
	 *            the new level
	 */
	public void setLevel(final int level) {
		this.level = level;
		if (levelLabel != null) {
			levelLabel.setText(Integer.toString(level));
		}
	}

	/**
	 * Sets the lines.
	 * 
	 * @param lines
	 *            the new lines
	 */
	public void setLines(final int lines) {
		this.lines = lines;
		if (rowsLabel != null) {
			rowsLabel.setText(Integer.toString(lines));
		}
	}

	/**
	 * Sets the score.
	 * 
	 * @param score
	 *            the new score
	 */
	public void setScore(final int score) {
		this.score = score;
		if (scoreLabel != null) {
			scoreLabel.setText(Integer.toString(score));
		}
	}

	/*
	 * (non-Javadoc)
	 * @see tc.de.krawallmann.slick.game.AbstractMMenuState#update(org.newdawn
	 * .slick.GameContainer, org.newdawn.slick.state.StateBasedGame, int)
	 */
	@Override
	public void update(final GameContainer container, final StateBasedGame game, final int delta)
			throws SlickException {
		super.update(container, game, delta);
		if (Language.getString("EnterScoreState.14").contains(nameField.getText()) || Language.getString("EnterScoreState.15").contains(nameField.getText())) { //$NON-NLS-1$ //$NON-NLS-2$
			okButton.setEnabled(false);
		} else {
			okButton.setEnabled(true);
		}
		if(!nameField.hasKeyboardFocus()&&nameField.getText().trim().isEmpty()){
			nameField.setText(lastEnteredName);
		}else if(nameField.hasKeyboardFocus()&&nameField.getText().trim().equals(Language.getString("EnterScoreState.1"))){
			nameField.setText("");
		}
	}

	/*
	 * (non-Javadoc)
	 * @see tc.de.krawallmann.twlslick.BasicTWLGameState#createRootPane()
	 */
	@Override
	protected RootPane createRootPane() {
		final RootPane pane = super.createRootPane();

		// Set root theme
		pane.setTheme(""); //$NON-NLS-1$

		// Create the widgets
		nameField = new EditField();
		nameField.setTooltipContent(Language.getString("EnterScoreState.8")); //$NON-NLS-1$
		nameField.setMaxTextLength(20);
		nameField.setText(lastEnteredName);

		nameTextLabel = new MulticolorLabel(Language.getString("EnterScoreState.2")); //$NON-NLS-1$
		nameTextLabel.setColor(MulticolorLabel.Color.RED);
		nameTextLabel.setTheme(NormalGameplayState.MULTICOLORLABEL40);

		scoreLabel = new Label(Integer.toString(score));
		scoreLabel.setTooltipContent(Language.getString("EnterScoreState.9")); //$NON-NLS-1$
		scoreLabel.setTheme("gridlabel"); //$NON-NLS-1$

		rowsLabel = new Label(Integer.toString(lines));
		rowsLabel.setTooltipContent(Language.getString("EnterScoreState.10")); //$NON-NLS-1$
		rowsLabel.setTheme("gridlabel"); //$NON-NLS-1$

		levelLabel = new Label(Integer.toString(level));
		levelLabel.setTooltipContent(Language.getString("EnterScoreState.11")); //$NON-NLS-1$
		levelLabel.setTheme("gridlabel"); //$NON-NLS-1$

		levelTextLabel = new MulticolorLabel(Language.getString("EnterScoreState.0")); //$NON-NLS-1$
		levelTextLabel.setColor(MulticolorLabel.Color.RED);
		levelTextLabel.setTheme(NormalGameplayState.MULTICOLORLABEL40);

		scoreTextLabel = new MulticolorLabel(Language.getString("EnterScoreState.6")); //$NON-NLS-1$
		scoreTextLabel.setColor(MulticolorLabel.Color.RED);
		scoreTextLabel.setTheme(NormalGameplayState.MULTICOLORLABEL40);

		rowsTextLabel = new MulticolorLabel(Language.getString("EnterScoreState.7")); //$NON-NLS-1$
		rowsTextLabel.setColor(MulticolorLabel.Color.RED);
		rowsTextLabel.setTheme(NormalGameplayState.MULTICOLORLABEL40);

		scoresLabel = new Label(Language.getString("EnterScoreState.3")); //$NON-NLS-1$
		scoresLabel.setTheme("label60"); //$NON-NLS-1$

		backButton = new Button(Language.getString("EnterScoreState.4")); //$NON-NLS-1$
		backButton.setTooltipContent(Language.getString("EnterScoreState.12")); //$NON-NLS-1$
		backButton.setTheme("button40"); //$NON-NLS-1$

		okButton = new Button(Language.getString("EnterScoreState.5")); //$NON-NLS-1$
		okButton.setTooltipContent(Language.getString("EnterScoreState.13")); //$NON-NLS-1$
		okButton.setTheme("button40"); //$NON-NLS-1$
		okButton.setEnabled(false);

		// Add callbacks
		okButton.addCallback(new Runnable() {
			@Override
			public void run() {
				if (SettingsExtension.getSetting(GravoBlocksGame.USE_SOUND)) {
					click.play();
				}
				lastEnteredName = nameField.getText();
				getGame().getExtension(HighscoresExtension.class).addScore(
						new Score(nameField.getText(), score, level, lines, gamemode));
				getGame().getExtension(HighscoresExtension.class).store();
				getGame().enterState(GravoBlocksGame.VIEWSCORESSTATE, new FadeOutTransition(),
						new FadeInTransition());
			}
		});

		backButton.addCallback(new Runnable() {
			@Override
			public void run() {
				if (SettingsExtension.getSetting(GravoBlocksGame.USE_SOUND)) {
					click.play();
				}
				getGame().enterState(GravoBlocksGame.VIEWSCORESSTATE, new FadeOutTransition(),
						new FadeInTransition());
			}
		});

		// Add the widgets
		pane.add(backButton);
		pane.add(okButton);
		pane.add(scoresLabel);
		pane.add(scoreLabel);
		pane.add(levelLabel);
		pane.add(nameField);
		pane.add(rowsLabel);
		pane.add(nameTextLabel);
		pane.add(scoreTextLabel);
		pane.add(levelTextLabel);
		pane.add(rowsTextLabel);

		// Make the widgets focusable
		makeFocusable(backButton);
		makeFocusable(okButton);

		return pane;
	}
}
